// CZ I/O 库
// 提供文件和流操作

const std = @import("std");
const cz_std = @import("cz_std.zig");
const Allocator = cz_std.Allocator;

// ============ 文件操作 ============

pub const File = struct {
    handle: std.fs.File,
    
    pub fn open(path: []const u8, mode: OpenMode) !File {
        const flags = switch (mode) {
            .read => std.fs.File.OpenFlags{},
            .write => std.fs.File.OpenFlags{ .mode = .write_only },
            .read_write => std.fs.File.OpenFlags{ .mode = .read_write },
        };
        
        const handle = try std.fs.cwd().openFile(path, flags);
        return File{ .handle = handle };
    }
    
    pub fn create(path: []const u8) !File {
        const handle = try std.fs.cwd().createFile(path, .{});
        return File{ .handle = handle };
    }
    
    pub fn close(self: *File) void {
        self.handle.close();
    }
    
    pub fn read(self: *File, buffer: []u8) !usize {
        return try self.handle.read(buffer);
    }
    
    pub fn readAll(self: *File, allocator: Allocator, max_size: usize) ![]u8 {
        return try self.handle.readToEndAlloc(allocator, max_size);
    }
    
    pub fn write(self: *File, data: []const u8) !usize {
        return try self.handle.write(data);
    }
    
    pub fn writeAll(self: *File, data: []const u8) !void {
        try self.handle.writeAll(data);
    }
    
    pub fn seek(self: *File, pos: i64, whence: SeekFrom) !u64 {
        const seek_from = switch (whence) {
            .start => std.fs.File.SeekableStream.SeekFrom.start,
            .current => std.fs.File.SeekableStream.SeekFrom.current,
            .end => std.fs.File.SeekableStream.SeekFrom.end,
        };
        return try self.handle.seekTo(pos);
    }
    
    pub fn getPos(self: *File) !u64 {
        return try self.handle.getPos();
    }
    
    pub fn getSize(self: *File) !u64 {
        const stat = try self.handle.stat();
        return stat.size;
    }
};

pub const OpenMode = enum {
    read,
    write,
    read_write,
};

pub const SeekFrom = enum {
    start,
    current,
    end,
};

// ============ 路径操作 ============

pub const Path = struct {
    pub fn join(allocator: Allocator, parts: []const []const u8) ![]u8 {
        return try std.fs.path.join(allocator, parts);
    }
    
    pub fn dirname(path: []const u8) []const u8 {
        return std.fs.path.dirname(path) orelse "";
    }
    
    pub fn basename(path: []const u8) []const u8 {
        return std.fs.path.basename(path);
    }
    
    pub fn extension(path: []const u8) []const u8 {
        return std.fs.path.extension(path);
    }
    
    pub fn isAbsolute(path: []const u8) bool {
        return std.fs.path.isAbsolute(path);
    }
};

// ============ 目录操作 ============

pub const Dir = struct {
    pub fn create(path: []const u8) !void {
        try std.fs.cwd().makeDir(path);
    }
    
    pub fn createAll(path: []const u8) !void {
        try std.fs.cwd().makePath(path);
    }
    
    pub fn remove(path: []const u8) !void {
        try std.fs.cwd().deleteDir(path);
    }
    
    pub fn removeAll(path: []const u8) !void {
        try std.fs.cwd().deleteTree(path);
    }
    
    pub fn exists(path: []const u8) bool {
        std.fs.cwd().access(path, .{}) catch return false;
        return true;
    }
    
    pub fn list(allocator: Allocator, path: []const u8) ![][]const u8 {
        var dir = try std.fs.cwd().openDir(path, .{ .iterate = true });
        defer dir.close();
        
        var result = cz_std.ArrayList([]const u8).init(allocator);
        defer result.deinit();
        
        var iter = dir.iterate();
        while (try iter.next()) |entry| {
            const name = try allocator.dupe(u8, entry.name);
            try result.append(name);
        }
        
        return try result.toOwnedSlice();
    }
};

// ============ 便捷函数 ============

pub fn readFile(allocator: Allocator, path: []const u8) ![]u8 {
    return try std.fs.cwd().readFileAlloc(allocator, path, 100 * 1024 * 1024);
}

pub fn writeFile(path: []const u8, data: []const u8) !void {
    var file = try File.create(path);
    defer file.close();
    try file.writeAll(data);
}

pub fn appendFile(path: []const u8, data: []const u8) !void {
    var file = try std.fs.cwd().openFile(path, .{ .mode = .write_only });
    defer file.close();
    try file.seekFromEnd(0);
    try file.writeAll(data);
}

pub fn fileExists(path: []const u8) bool {
    std.fs.cwd().access(path, .{}) catch return false;
    return true;
}

pub fn deleteFile(path: []const u8) !void {
    try std.fs.cwd().deleteFile(path);
}

pub fn copyFile(src: []const u8, dest: []const u8) !void {
    try std.fs.cwd().copyFile(src, std.fs.cwd(), dest, .{});
}

pub fn renameFile(old_path: []const u8, new_path: []const u8) !void {
    try std.fs.cwd().rename(old_path, new_path);
}
